package com.cqie.service.impl;

import com.cqie.dto.TokenUserLoginDto;
import com.cqie.dto.entrepot.*;
import com.cqie.entity.EntrepotDrugInfo;
import com.cqie.exception.SpecialException;
import com.cqie.mapper.EntrepotDrugInfoMapper;
import com.cqie.mapper.user.DoctorInfoMapper;
import com.cqie.service.*;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cqie.threadlocal.UserThreadLocal;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;

import java.util.List;
import java.util.Objects;

/**
 * <p>
 * 仓库药品信息 服务实现类
 * </p>
 *
 * @author 不吃海鲜
 * @since 2024-12-19
 */
@Service
public class EntrepotDrugInfoServiceImpl extends ServiceImpl<EntrepotDrugInfoMapper, EntrepotDrugInfo> implements IEntrepotDrugInfoService {

    @Resource
    private EntrepotDrugInfoMapper entrepotDrugInfoMapper;
    @Resource
    private DoctorInfoMapper doctorInfoMapper;

    private final IMedicalDrugInfoService medicalDrugInfoService;

    private final IEntrepotRecordInfoService entrepotRecordInfoService;

    private final IEntrepotWarehouseInfoService entrepotWarehouseInfoService;
    private final IDoctorInfoService doctorInfoService;


    public EntrepotDrugInfoServiceImpl(IMedicalDrugInfoService medicalDrugInfoService,
                                       IEntrepotRecordInfoService entrepotRecordInfoService,
                                       IEntrepotWarehouseInfoService entrepotWarehouseInfoService,
                                       IDoctorInfoService doctorInfoService ) {
        this.medicalDrugInfoService = medicalDrugInfoService;
        this.entrepotRecordInfoService = entrepotRecordInfoService;
        this.entrepotWarehouseInfoService = entrepotWarehouseInfoService;
        this.doctorInfoService = doctorInfoService;

    }

    /**
     * 新增仓库药品信息
     *
     * @param addEntrepotDrugInfoDto
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean saveEntrepotDrugInfo(AddEntrepotDrugInfoDto addEntrepotDrugInfoDto) throws SpecialException {

        // 获取登陆账号信息
        TokenUserLoginDto tokenDto = UserThreadLocal.get(TokenUserLoginDto.class);

        if (ObjectUtils.isEmpty(addEntrepotDrugInfoDto.getDrugId())) {
            throw new SpecialException("药品id不能为空");
        }

        if (ObjectUtils.isEmpty(addEntrepotDrugInfoDto.getWarehouseId())) {
            throw new SpecialException("仓库id不能为空");
        }

        if (addEntrepotDrugInfoDto.getDrugNumber() < 0) {
            throw new SpecialException("药品数量不能小于0");
        }

        var warehouseId = addEntrepotDrugInfoDto.getWarehouseId();
        var drugId = addEntrepotDrugInfoDto.getDrugId();

        // 获取仓库信息
        var entrepotWarehouseInfo =
                entrepotWarehouseInfoService.getEntrepotWarehouseInfo(warehouseId);

        // 获取药品信息
        var medicalDrugInfo = medicalDrugInfoService.getMedicalDrugInfoByDrugId(drugId);


        // 获取该仓库的最大容量
        var maxNumber = Integer.valueOf(entrepotWarehouseInfo.getWarehouseMaxCount());


        // 根据仓库id和药品id查询仓库药品信息列表里面是否存在值
        var result = getEntrepotDrugInfoByWarehouseId(warehouseId, drugId);


        // 然后添加记录表
        AddEntrepotRecordDto addEntrepotRecordDto = new AddEntrepotRecordDto();
        // 仓库id
        addEntrepotRecordDto.setStockWarehouseId(addEntrepotDrugInfoDto.getWarehouseId());
        // 仓库名称
        addEntrepotRecordDto.setWarehouseName(entrepotWarehouseInfo.getWarehouseName());
        // 药品id
        addEntrepotRecordDto.setDrugId(addEntrepotDrugInfoDto.getDrugId());
        // 药品编码
        addEntrepotRecordDto.setDrugCode(medicalDrugInfo.getDrugCode());
        // 药品名称
        addEntrepotRecordDto.setDrugName(medicalDrugInfo.getDrugName());
        // 进货/取货名称
        addEntrepotRecordDto.setWarehouseRecordName("进货");
        // 进货/取货代码
        addEntrepotRecordDto.setWarehouseRecordCode("1");
        // 操作数量
        addEntrepotRecordDto.setOperationNumber(addEntrepotDrugInfoDto.getDrugNumber());
        // 授权
        addEntrepotRecordDto.setAuthorizationSign("0");
        // 操作人id
        addEntrepotRecordDto.setInitiatorDoctorId(tokenDto.getDoctorId());
        // 操作人姓名
        addEntrepotRecordDto.setInitiatorDoctorName(doctorInfoMapper.getDoctorNameByDoctorId(tokenDto.getDoctorId()));


        // 不存在值，直接新增记录表和仓库药品信息
        if (ObjectUtils.isEmpty(result)) {
            // 如果数量为0则不会新增进货记录
            if (!Objects.equals(addEntrepotDrugInfoDto.getDrugNumber(), Integer.valueOf(0))) {
                // 药品数量超过仓库最大容量
                if (maxNumber < addEntrepotDrugInfoDto.getDrugNumber()) {
                    throw new SpecialException("药品数量超过仓库最大容量");
                }
                // 新增进货记录
                entrepotRecordInfoService.saveStockRecord(addEntrepotRecordDto);
            }
            entrepotDrugInfoMapper.saveEntrepotDrugInfo(addEntrepotDrugInfoDto);
        }
        // 存在值 ， 直接判断是否超过最大值
        // 然后更新仓库药品信息数量
        else {
            var sum = result.getDrugNumber() + addEntrepotDrugInfoDto.getDrugNumber();

            if (maxNumber < sum) {
                throw new SpecialException("药品数量超过仓库最大容量");
            }

            // 新增进货记录
            EntrepotDrugInfoDto entrepotDrugInfoDto = new EntrepotDrugInfoDto();
            entrepotDrugInfoDto.setDrugNumber(sum);
            entrepotDrugInfoDto.setWarehouseId(addEntrepotDrugInfoDto.getWarehouseId());
            entrepotDrugInfoDto.setDrugId(addEntrepotDrugInfoDto.getDrugId());


            entrepotRecordInfoService.saveStockRecord(addEntrepotRecordDto);
            entrepotDrugInfoMapper.updateDrugNumber(entrepotDrugInfoDto);
        }

        return true;

    }

    /**
     * 根据仓库ids查询仓库药品信息列表
     *
     * @param warehouseId
     * @return
     */
    @Override
    public List<EntrepotDrugInfoListDto> getEntrepotDrugInfoByWarehouseIdList(Integer warehouseId,
                                                                              Integer pageSize,
                                                                              Integer pageIndex) throws SpecialException {
        if (ObjectUtils.isEmpty(warehouseId)) {
            throw new SpecialException("仓库id不能为空");
        }

        // 仓库药品信息列表
        var EntrepotDrugInfoList = entrepotDrugInfoMapper.getEntrepotDrugInfoByWarehouseIdList(warehouseId);

        // 药品id列表
        List<Integer> drugIdList =
                EntrepotDrugInfoList.stream().map(EntrepotDrugInfoByWarehouseIdDto::getDrugId).toList();
        // 药品信息列表
        var entrepotDrugInfoList = medicalDrugInfoService.getMedicalDrugInfoByDrugIdList(drugIdList, pageSize,
                pageIndex);

        // 将药品信息列表中的药品名称和药品规格添加到仓库药品信息列表中
        for (EntrepotDrugInfoListDto entrepotDrugInfo : entrepotDrugInfoList) {
            for (EntrepotDrugInfoByWarehouseIdDto EntrepotDrugInfo : EntrepotDrugInfoList) {

                if (Objects.equals(EntrepotDrugInfo.getDrugId(), entrepotDrugInfo.getDrugId())) {
                    entrepotDrugInfo.setDrugNumber(EntrepotDrugInfo.getDrugNumber());
                    break;
                }

            }
        }

        return entrepotDrugInfoList;
    }

    /**
     * 根据仓库id和药品id查询仓库药品信息
     *
     * @param warehouseId 仓库id
     * @param drugId      药品id
     * @return
     */
    public EntrepotDrugInfoByWarehouseIdDto getEntrepotDrugInfoByWarehouseId(Integer warehouseId, Integer drugId) {
        return entrepotDrugInfoMapper.getEntrepotDrugInfoByWarehouseId(warehouseId, drugId);
    }
}
